package demo.utils;

import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import org.codehaus.groovy.runtime.EncodingGroovyMethods;
import org.junit.Test;

import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ScriptRuleExecutorDemo {


    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(16);
        int i = 100_0000;
        while (i > 0) {
            executor.submit(() -> {
                String scriptText = "x > 30";
                Map variable = new HashMap();
                variable.put("x", 40);
                try {
                    Object result = RuleExecutorUtil.evaluate(scriptText, variable);
                    System.out.println(result);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });

            i--;
        }
        executor.shutdown();
    }

    /**
     * 创建线程工厂
     *
     * @param corePoolSize    核心线程池大小
     * @param maximumPoolSize 最大线程池大小
     * @param keepAliveTime   线程最大空闲时间
     * @param unit            时间单位
     * @param workQueue       线程等待队列
     * @param threadFactory   线程创建工厂
     * @param handler         拒绝策略
     */
    public static ThreadPoolExecutor build(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                                           BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        return new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory,
                handler);
    }

    @Test
    public void test1() throws NoSuchAlgorithmException {
        String scriptText = "x > 30";
        Map variable = new HashMap();
        variable.put("x", 40);
        Object result = RuleExecutorUtil.evaluate(scriptText, variable);
        System.out.println(result);
    }

    @Test
    public void test2() throws NoSuchAlgorithmException {
        String scriptText = "x + y > 30";
        Map variable = new HashMap();
        variable.put("x", 20);
        variable.put("y", 10);
        Object result = RuleExecutorUtil.evaluate(scriptText, variable);
        System.out.println(result);
    }

    @Test
    public void test3() throws NoSuchAlgorithmException {
        String scriptText = "(x + y) * z ";
        Map variable = new HashMap();
        variable.put("x", 2);
        variable.put("y", 10);
        variable.put("z", 3);
        Object result = RuleExecutorUtil.evaluate(scriptText, variable);
        System.out.println(result);
    }

    /**
     * 与(&&)：逻辑规则是两真才真。与and等同。
     */
    @Test
    public void testAnd() throws NoSuchAlgorithmException {
        String scriptText = "x && y";
        Map variable = new HashMap();
        variable.put("x", true);
        variable.put("y", false);
        Object result = RuleExecutorUtil.evaluate(scriptText, variable);
        System.out.println(result);
    }

    /**
     * 或(||)：逻辑规则是只有一个为真就为真。与or等同。
     */
    @Test
    public void testOr() throws NoSuchAlgorithmException {
        String scriptText = "x || y";
        Map variable = new HashMap();
        variable.put("x", true);
        variable.put("y", false);
        Object result = RuleExecutorUtil.evaluate(scriptText, variable);
        System.out.println(result);
    }

    /**
     * 非(！)：逻辑规则是反转操作数的含义。与not等同。
     */
    @Test
    public void testNot() throws NoSuchAlgorithmException {
        String scriptText = "!x";
        Map variable = new HashMap();
        variable.put("x", true);
        Object result = RuleExecutorUtil.evaluate(scriptText, variable);
        System.out.println(result);
    }

    /**
     * 异或(^)：逻辑规则是两个不同就为真。
     */
    @Test
    public void testXor() throws NoSuchAlgorithmException {
        String scriptText = "x ^ y";
        Map variable = new HashMap();
        variable.put("x", true);
        variable.put("y", false);
        Object result = RuleExecutorUtil.evaluate(scriptText, variable);
        System.out.println(result);
    }

    @Test
    public void testDoubleNan(){
        String scriptText = "x > 2.0";
        Map variable = new HashMap();
        variable.put("x", Double.NaN);
        Object result = RuleExecutorUtil.evaluate(scriptText, variable);
        System.out.println(result);

        System.out.println(Double.NaN > 2.0);
    }


    @Test
    public void test5XX(){
        String scriptText = "(rate5xx > 0.05 || rt > 10 && (hbRtRatio > 1.0 || tbRatio > 1.0)) " +
                "&& (hbDiff > 20 ||tbDiff > 20) && (hbRatio > 0.3 ||tbRatio > 0.3) ";
        Map variable = new HashMap();
        variable.put("hbDiff", 0);
        variable.put("tbRatio", 0);
        variable.put("rt", 0);
        variable.put("tbDiff", -1);
        variable.put("hbRatio", 0);
        variable.put("tbRt", 1);
        variable.put("hbRt", 0);
        variable.put("hbRtDiff", 0);
        variable.put("hbRtRatio", 0);
        variable.put("tbRtDiff", 0);
        variable.put("tbValue", 0);
        variable.put("hbValue", 0);
        variable.put("value", 0);
        variable.put("rate5xx", 0);
        Object result = RuleExecutorUtil.evaluate(scriptText, variable);
        System.out.println(result);

    }

    @Test
    public void test0(){
        String scriptText = "value * 1 / (100.0*1024*1024*1024)";
        Map variable = new HashMap();
        variable.put("value", 60000000000L);
        Object result = RuleExecutorUtil.evaluate(scriptText, variable);
        System.out.println(result);

    }



}
